#ifndef FirstService_H
#define FirstService_H

#include <thrift/transport/TBufferTransports.h>
#include <functional>
namespace apache { namespace thrift { namespace async {
class TAsyncChannel;
}}}

#include <thrift/TDispatchProcessor.h>
#include <thrift/async/TAsyncDispatchProcessor.h>
#include <thrift/async/TAsyncChannel.h>
#include <thrift/async/TConcurrentClientSyncInfo.h>
#include <memory>
#include "ThriftTest_types.h"

namespace thrift { namespace test {

#ifdef _MSC_VER
    #pragma warning(push)
    #pragma warning(disable : 4250) //inheriting methods via dominance 
#endif

class FirstServiceIf
{
public:
    virtual ~FirstServiceIf() {}
    virtual void testString(std::string& _return, const std::string& thing) = 0;
};

class FirstServiceIfFactory
{
public:
    typedef FirstServiceIf Handler;

    virtual ~FirstServiceIfFactory() {}

    virtual FirstServiceIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) = 0;
    virtual void releaseHandler(FirstServiceIf* /* handler */) = 0;
};

class FirstServiceIfSingletonFactory : virtual public FirstServiceIfFactory
{
public:
    FirstServiceIfSingletonFactory(const ::std::shared_ptr<FirstServiceIf>& iface) : iface_(iface) {}

    virtual ~FirstServiceIfSingletonFactory() {}

    virtual FirstServiceIf* getHandler(const ::apache::thrift::TConnectionInfo&) override
    {
        return iface_.get();
    }
    virtual void releaseHandler(FirstServiceIf* /* handler */) override {}

protected:
    ::std::shared_ptr<FirstServiceIf> iface_;
};

class FirstServiceNull : virtual public FirstServiceIf
{
public:
    virtual ~FirstServiceNull() {}
    void testString(std::string& /* _return */, const std::string& /* thing */) override
    {
        return;
    }
};

typedef struct _FirstService_testString_args__isset
{
    _FirstService_testString_args__isset() : thing(false) {}
    bool thing :1;
} _FirstService_testString_args__isset;

class FirstService_testString_args
{
public:
    FirstService_testString_args(const FirstService_testString_args&);
    FirstService_testString_args(FirstService_testString_args&&) noexcept;
    FirstService_testString_args& operator=(const FirstService_testString_args&);
    FirstService_testString_args& operator=(FirstService_testString_args&&) noexcept;
    FirstService_testString_args() noexcept
                                 : thing()
    {
    }
    virtual ~FirstService_testString_args() noexcept;

    std::string thing;

    _FirstService_testString_args__isset __isset;

    void __set_thing(const std::string& val);

    bool operator == (const FirstService_testString_args & rhs) const
    {
        if (!(thing == rhs.thing))
            return false;
        return true;
    }
    bool operator != (const FirstService_testString_args &rhs) const
    {
        return !(*this == rhs);
    }

    bool operator < (const FirstService_testString_args & ) const;

    uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
    uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
};


class FirstService_testString_pargs
{
public:
    virtual ~FirstService_testString_pargs() noexcept;

    const std::string* thing;

    uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
};

typedef struct _FirstService_testString_result__isset
{
    _FirstService_testString_result__isset() : success(false) {}
    bool success :1;
} _FirstService_testString_result__isset;

class FirstService_testString_result
{
public:
    FirstService_testString_result(const FirstService_testString_result&);
    FirstService_testString_result(FirstService_testString_result&&) noexcept;
    FirstService_testString_result& operator=(const FirstService_testString_result&);
    FirstService_testString_result& operator=(FirstService_testString_result&&) noexcept;
    FirstService_testString_result() noexcept
                                   : success()
    {
    }
    virtual ~FirstService_testString_result() noexcept;

    std::string success;

    _FirstService_testString_result__isset __isset;

    void __set_success(const std::string& val);

    bool operator == (const FirstService_testString_result & rhs) const
    {
        if (!(success == rhs.success))
            return false;
        return true;
    }
    bool operator != (const FirstService_testString_result &rhs) const
    {
        return !(*this == rhs);
    }

    bool operator < (const FirstService_testString_result & ) const;

    uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
    uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
};

typedef struct _FirstService_testString_presult__isset
{
    _FirstService_testString_presult__isset() : success(false) {}
    bool success :1;
} _FirstService_testString_presult__isset;

class FirstService_testString_presult
{
public:
    virtual ~FirstService_testString_presult() noexcept;

    std::string* success;

    _FirstService_testString_presult__isset __isset;

    uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
    uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
};

class FirstServiceClient : virtual public FirstServiceIf
{
public:
    FirstServiceClient(std::shared_ptr<::apache::thrift::protocol::TProtocol> prot)
    {
        setProtocol(prot);
    }
    FirstServiceClient(std::shared_ptr<::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr<::apache::thrift::protocol::TProtocol> oprot)
    {
        setProtocol(iprot, oprot);
    }

private:
    void setProtocol(std::shared_ptr<::apache::thrift::protocol::TProtocol> prot) 
    {
        setProtocol(prot, prot);
    }
    void setProtocol(std::shared_ptr<::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr<::apache::thrift::protocol::TProtocol> oprot)
    {
        piprot_ = iprot;
        poprot_ = oprot;
        iprot_  = iprot.get();
        oprot_  = oprot.get();
    }

public:
    std::shared_ptr<::apache::thrift::protocol::TProtocol> getInputProtocol()
    {
        return piprot_;
    }
    std::shared_ptr<::apache::thrift::protocol::TProtocol> getOutputProtocol()
    {
        return poprot_;
    }

    void testString(std::string& _return, const std::string& thing) override;
    void send_testString(const std::string& thing);
    void recv_testString(std::string& _return);

protected:
    std::shared_ptr<::apache::thrift::protocol::TProtocol> piprot_;
    std::shared_ptr<::apache::thrift::protocol::TProtocol> poprot_;
    ::apache::thrift::protocol::TProtocol* iprot_;
    ::apache::thrift::protocol::TProtocol* oprot_;
};

class FirstServiceProcessor : public ::apache::thrift::TDispatchProcessor
{
protected:
    ::std::shared_ptr<FirstServiceIf> iface_;
    virtual bool dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext) override;

private:
    typedef void (FirstServiceProcessor::*ProcessFunction)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*);
    typedef std::map<std::string, ProcessFunction> ProcessMap;
    ProcessMap processMap_;
    void process_testString(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);

public:
    FirstServiceProcessor(::std::shared_ptr<FirstServiceIf> iface) : iface_(iface) 
    {
        processMap_["testString"] = &FirstServiceProcessor::process_testString;
    }

    virtual ~FirstServiceProcessor() {}
};

class FirstServiceProcessorFactory : public ::apache::thrift::TProcessorFactory
{
public:
    FirstServiceProcessorFactory(const ::std::shared_ptr<FirstServiceIfFactory>& handlerFactory) noexcept : handlerFactory_(handlerFactory)
    {
    }

    ::std::shared_ptr<::apache::thrift::TProcessor> getProcessor(const ::apache::thrift::TConnectionInfo& connInfo) override;

protected:
    ::std::shared_ptr<FirstServiceIfFactory> handlerFactory_;
};

class FirstServiceMultiface : virtual public FirstServiceIf
{
 public:
    FirstServiceMultiface(std::vector<std::shared_ptr<FirstServiceIf>>& ifaces) : ifaces_(ifaces) 
    {
    }

    virtual ~FirstServiceMultiface()
    {
    }

protected:
    std::vector<std::shared_ptr<FirstServiceIf>> ifaces_;
    FirstServiceMultiface() {}
    void add(::std::shared_ptr<FirstServiceIf> iface)
    {
        ifaces_.push_back(iface);
    }

public:
    void testString(std::string& _return, const std::string& thing) override
    {
        size_t sz = ifaces_.size();
        size_t i = 0;
        for (; i < (sz - 1); ++i) 
        {
            ifaces_[i]->testString(_return, thing);
        }
        ifaces_[i]->testString(_return, thing);
        return;
    }

};

// The 'concurrent' client is a thread safe client that correctly handles
// out of order responses.  It is slower than the regular client, so should
// only be used when you need to share a connection among multiple threads
class FirstServiceConcurrentClient : virtual public FirstServiceIf
{
public:
    FirstServiceConcurrentClient(std::shared_ptr<::apache::thrift::protocol::TProtocol> prot, std::shared_ptr<::apache::thrift::async::TConcurrentClientSyncInfo> sync): sync_(sync)
    {
        setProtocol(prot);
    }
    FirstServiceConcurrentClient(std::shared_ptr<::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr<::apache::thrift::protocol::TProtocol> oprot, std::shared_ptr<::apache::thrift::async::TConcurrentClientSyncInfo> sync): sync_(sync)
    {
        setProtocol(iprot, oprot);
    }

private:
    void setProtocol(std::shared_ptr<::apache::thrift::protocol::TProtocol> prot) 
    {
        setProtocol(prot, prot);
    }
    void setProtocol(std::shared_ptr<::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr<::apache::thrift::protocol::TProtocol> oprot)
    {
        piprot_ = iprot;
        poprot_ = oprot;
        iprot_  = iprot.get();
        oprot_  = oprot.get();
    }

public:
    std::shared_ptr<::apache::thrift::protocol::TProtocol> getInputProtocol()
    {
        return piprot_;
    }
    std::shared_ptr<::apache::thrift::protocol::TProtocol> getOutputProtocol()
    {
        return poprot_;
    }

    void testString(std::string& _return, const std::string& thing) override;
    int32_t send_testString(const std::string& thing);
    void recv_testString(std::string& _return, const int32_t seqid);

protected:
    std::shared_ptr<::apache::thrift::protocol::TProtocol> piprot_;
    std::shared_ptr<::apache::thrift::protocol::TProtocol> poprot_;
    ::apache::thrift::protocol::TProtocol* iprot_;
    ::apache::thrift::protocol::TProtocol* oprot_;
    std::shared_ptr<::apache::thrift::async::TConcurrentClientSyncInfo> sync_;
};

class FirstServiceCobClient;

class FirstServiceCobClIf
{
public:
    virtual ~FirstServiceCobClIf() {}
    virtual void testString(::std::function<void(FirstServiceCobClient* client)> cob, const std::string& thing) = 0;
};

class FirstServiceCobSvIf
{
public:
    virtual ~FirstServiceCobSvIf() {}
    virtual void testString(::std::function<void(std::string const& _return)> cob, const std::string& thing) = 0;
};

class FirstServiceCobSvIfFactory
{
public:
    typedef FirstServiceCobSvIf Handler;

    virtual ~FirstServiceCobSvIfFactory() {}

    virtual FirstServiceCobSvIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) = 0;
    virtual void releaseHandler(FirstServiceCobSvIf* /* handler */) = 0;
};

class FirstServiceCobSvIfSingletonFactory : virtual public FirstServiceCobSvIfFactory
{
public:
    FirstServiceCobSvIfSingletonFactory(const ::std::shared_ptr<FirstServiceCobSvIf>& iface) : iface_(iface) {}

    virtual ~FirstServiceCobSvIfSingletonFactory() {}

    virtual FirstServiceCobSvIf* getHandler(const ::apache::thrift::TConnectionInfo&) override
    {
        return iface_.get();
    }
    virtual void releaseHandler(FirstServiceCobSvIf* /* handler */) override {}

protected:
    ::std::shared_ptr<FirstServiceCobSvIf> iface_;
};

class FirstServiceCobSvNull : virtual public FirstServiceCobSvIf
{
public:
    virtual ~FirstServiceCobSvNull() {}
    void testString(::std::function<void(std::string const& _return)> cob, const std::string& /* thing */) override
    {
        std::string _return;
        return cob(_return);
    }
};

class FirstServiceCobClient : virtual public FirstServiceCobClIf
{
public:
    FirstServiceCobClient(std::shared_ptr< ::apache::thrift::async::TAsyncChannel> channel, ::apache::thrift::protocol::TProtocolFactory* protocolFactory) :
      channel_(channel),
      itrans_(new ::apache::thrift::transport::TMemoryBuffer()),
      otrans_(new ::apache::thrift::transport::TMemoryBuffer()),
      piprot_(protocolFactory->getProtocol(itrans_)),
      poprot_(protocolFactory->getProtocol(otrans_)) {
      iprot_ = piprot_.get();
      oprot_ = poprot_.get();
    }
    ::std::shared_ptr< ::apache::thrift::async::TAsyncChannel> getChannel() {
      return channel_;
    }
    virtual void completed__(bool /* success */) {}

    void testString(::std::function<void(FirstServiceCobClient* client)> cob, const std::string& thing) override;
    void send_testString(const std::string& thing);
    void recv_testString(std::string& _return);

protected:
    ::std::shared_ptr<::apache::thrift::async::TAsyncChannel> channel_;
    ::std::shared_ptr<::apache::thrift::transport::TMemoryBuffer> itrans_;
    ::std::shared_ptr<::apache::thrift::transport::TMemoryBuffer> otrans_;
    std::shared_ptr<::apache::thrift::protocol::TProtocol> piprot_;
    std::shared_ptr<::apache::thrift::protocol::TProtocol> poprot_;
    ::apache::thrift::protocol::TProtocol* iprot_;
    ::apache::thrift::protocol::TProtocol* oprot_;
};

class FirstServiceAsyncProcessor : public ::apache::thrift::async::TAsyncDispatchProcessor
{
protected:
    ::std::shared_ptr<FirstServiceCobSvIf> iface_;
    virtual void dispatchCall(::std::function<void(bool ok)> cob, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid) override;

private:
    typedef void (FirstServiceAsyncProcessor::*ProcessFunction)(::std::function<void(bool ok)>, int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*);
    typedef std::map<std::string, ProcessFunction> ProcessMap;
    ProcessMap processMap_;
    void process_testString(::std::function<void(bool ok)> cob, int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot);
    void return_testString(::std::function<void(bool ok)> cob, int32_t seqid, ::apache::thrift::protocol::TProtocol* oprot, void* ctx, const std::string& _return);
    void throw_testString(::std::function<void(bool ok)> cob, int32_t seqid, ::apache::thrift::protocol::TProtocol* oprot, void* ctx, ::apache::thrift::TDelayedException* _throw);

public:
    FirstServiceAsyncProcessor(::std::shared_ptr<FirstServiceCobSvIf> iface) : iface_(iface) 
    {
        processMap_["testString"] = &FirstServiceAsyncProcessor::process_testString;
    }

    virtual ~FirstServiceAsyncProcessor() {}
};

class FirstServiceAsyncProcessorFactory : public ::apache::thrift::async::TAsyncProcessorFactory
{
public:
    FirstServiceAsyncProcessorFactory(const ::std::shared_ptr<FirstServiceCobSvIfFactory>& handlerFactory) noexcept : handlerFactory_(handlerFactory)
    {
    }

    ::std::shared_ptr<::apache::thrift::async::TAsyncProcessor> getProcessor(const ::apache::thrift::TConnectionInfo& connInfo) override;

protected:
    ::std::shared_ptr<FirstServiceCobSvIfFactory> handlerFactory_;
};

#ifdef _MSC_VER
    #pragma warning( pop )
#endif

}} // namespace

#endif
